package com.personal.service.Impl;

import cn.hutool.core.util.IdUtil;
import com.personal.bo.CreateOrderBO;
import com.personal.enums.OrdersEnum;
import com.personal.exception.ExceptionUtils;
import com.personal.mapper.*;
import com.personal.pojo.GoldCoin;
import com.personal.pojo.OrderResources;
import com.personal.pojo.OrderStatus;
import com.personal.pojo.Orders;
import com.personal.service.OrderService;
import com.personal.service.ResourcesService;
import com.personal.utils.RedisUtils;
import com.personal.utils.Result;
import com.personal.vo.ResourcesVO;
import com.personal.vo.ShopCartVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrdersMapper ordersMapper;

    @Autowired
    private OrderStatusMapper orderStatusMapper;

    @Autowired
    private OrderResourcesMapper orderResourcesMapper;

    @Autowired
    private GoldCoinMapper goldCoinMapper;

    @Autowired
    private RedisUtils redisUtils;

    /**
     * 创建订单
     * @param createOrderBO
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public Result createOrder(CreateOrderBO createOrderBO) {
        log.info("创建订单接口");
        if (createOrderBO.getShopCartVOList().isEmpty() || createOrderBO.getUserId() == null||
            createOrderBO.getTotalAmount() == null) {
            ExceptionUtils.error(OrdersEnum.ORDERS_PARAM_ERROR);
        }

        //查询用户账户
        GoldCoin userAccount = goldCoinMapper.getUserAccount(createOrderBO.getUserId());
        if (userAccount.getGoldCoinBalance() < createOrderBO.getTotalAmount()) {
            ExceptionUtils.error(OrdersEnum.ORDERS_ACCOUNT_BALANCE_ENOUGH);
        }

        //创建订单，插入订单表
        Orders orders = new Orders();
        //生成该订单的唯一订单id
        String id = IdUtil.simpleUUID();
        orders.setId(id);
        orders.setUserId(createOrderBO.getUserId());
        orders.setTotalAmount(createOrderBO.getTotalAmount());
        orders.setIsDelete(0);
        orders.setIsComment(0);
        orders.setPayMethod(1);
        ordersMapper.saveOrder(orders);

        // 插入订单资源表, 通过资源id查询资源
        List<ShopCartVO> shopCartVOList = createOrderBO.getShopCartVOList();
        for (ShopCartVO shopCartVO : shopCartVOList) {
            OrderResources orderResources = new OrderResources();
            orderResources.setOrderId(id);
            orderResources.setResourcesId(shopCartVO.getResourcesId());
            orderResources.setResourcesImg(shopCartVO.getResourcesImgUrl());
            orderResources.setResourcesName(shopCartVO.getName());
            // TODO 这里后面引入vip系统的话需要更改
            orderResources.setPrice(shopCartVO.getPriceNormal());

            orderResourcesMapper.saveOrderResources(orderResources);

            //购买成功后删掉购物车中的该商品
            redisUtils.hdel(createOrderBO.getUserId().toString(),shopCartVO.getResourcesId().toString());
        }

        //插入订单状态表
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setId(id);
        orderStatus.setOrderStatus(30);
        orderStatus.setCreateTime(new Date());
        orderStatus.setPayTime(new Date());
        orderStatus.setSuccessTime(new Date());
        orderStatusMapper.saveOrderStatus(orderStatus);

        //进行账户扣钱，完成订单创建和资源购买
        GoldCoin goldCoin = new GoldCoin();
        goldCoin.setUserId(createOrderBO.getUserId());
        goldCoin.setGoldCoinBalance(userAccount.getGoldCoinBalance() - createOrderBO.getTotalAmount());

        goldCoin.setGoldCoinTotal(userAccount.getGoldCoinTotal() + createOrderBO.getTotalAmount());
        goldCoin.setCommissionTotal(0);
        Integer flag = goldCoinMapper.updateGoldCoinAccount(goldCoin);
        if (flag == null || flag != 1) {
            ExceptionUtils.error(OrdersEnum.ORDERS_BUY_ERROR);
        }
        
        return Result.success();
    }
}
